package main

import "fmt"

/*
算术运算、逻辑运算和比较运算的二元运算符，它们按照优先级递减的顺序排列
* / % << >> & &^
+ - | ^
== != < <= > >=
&&
||
*/

func main() {
	// test1()
	// test2()
	test3()
}

func test1() {
	var x uint8 = 1<<1 | 1<<5
	var y uint8 = 1<<1 | 1<<2

	fmt.Printf("%08b\n", x) // "00100010", the set {1, 5}
	fmt.Printf("%08b\n", y) // "00000110", the set {1, 2}

	fmt.Printf("%08b\n", x&y) // "00000010", the intersection {1}
	fmt.Printf("%08b\n", x|y) // "00100110", the union {1, 2, 5}
	fmt.Printf("%d\n", x)
	fmt.Printf("%d\n", y)
	fmt.Printf("%d\n", x|y)
	fmt.Printf("%08b\n", x^y)  // "00100100", the symmetric difference {2, 5}
	fmt.Printf("%08b\n", x&^y) // "00100000", the difference {5}

	for i := uint(0); i < 8; i++ {
		if x&(1<<i) != 0 { // membership test
			fmt.Println(i) // "1", "5"
		}
	}

	fmt.Printf("%08b\n", x<<1) // "01000100", the set {2, 6}
	fmt.Printf("%08b\n", x>>1) // "00010001", the set {0, 4}
}

func test2() {
	medals := []string{"gold", "silver", "bronze"}
	for i := len(medals) - 1; i >= 0; i-- {
		fmt.Println(medals[i]) // "bronze", "silver", "gold"
	}
}

func test3() {
	/*
		出于这个原因，无符号数往往只有在位运算或其它特殊的运算场景才会使用，就像bit集合、分析
		二进制文件格式或者是哈希和加密操作等。它们通常并不用于仅仅是表达非负数量的场合。
	*/
	a := 1
	u := uint(a)
	fmt.Println(a)     // 1
	fmt.Println(u)     // 1
	fmt.Println(a - 1) // 0
	fmt.Println(a - 2) // -1
	fmt.Println(u - 1) // 0
	fmt.Println(u - 2) // 18446744073709551615
}

func test4() {
	/*
		精度损失，并不按照四舍五入
	*/
	f := 3.141 // a float64
	i := int(f)
	fmt.Println(f, i) // "3.141 3"
	f = 1.99
	fmt.Println(int(f)) // "1"
}

func test5() {
	/*
		请注意fmt的两个使用技巧。
		通常Printf格式化字符串包含多个%参数时将会包含对应相同数量的额外操作数，
		但是%之后的[1]副词告诉Printf函数再次使用第一个操作数。
		第二，%后的#副词告诉Printf在用%o、%x或%X输出时生成0、0x或0X前缀。
	*/
	o := 0666
	fmt.Printf("%d %[1]o %#[1]o\n", o) // "438 666 0666"
	x := int64(0xdeadbeef)
	fmt.Printf("%d %[1]x %#[1]x %#[1]X\n", x)
	// Output:
	// 3735928559 deadbeef 0xdeadbeef 0XDEADBEEF

	/*
		字符使用%c参数打印，或者是用%q参数打印带单引号的字符
	*/
	ascii := 'a'
	unicode := '国'
	newline := '\n'
	fmt.Printf("%d %[1]c %[1]q\n", ascii)   // "97 a 'a'"
	fmt.Printf("%d %[1]c %[1]q\n", unicode) // "22269 国 '国'"
	fmt.Printf("%d %[1]q\n", newline)
	// "10 '\n'"
}
